<template>
  <div class="crud-opts">
    <span class="crud-opts-left">
      <!--左侧插槽-->
      <slot name="left" />
      <el-button
        v-if="crud.optShow.add"
        v-permission="permission.add"
        class="filter-item"
        size="mini"
        type="primary"
        icon="el-icon-plus"
        @click="crud.toAdd"
      >
        新增
      </el-button>
      <el-button
        v-if="crud.optShow.edit"
        v-permission="permission.edit"
        class="filter-item"
        size="mini"
        type="success"
        icon="el-icon-edit"
        :disabled="crud.selections.length !== 1"
        @click="crud.toEdit(crud.selections[0])"
      >
        修改
      </el-button>
      <el-button
        v-if="crud.optShow.del"
        v-permission="permission.del"
        slot="reference"
        class="filter-item"
        type="danger"
        icon="el-icon-delete"
        size="mini"
        :loading="crud.delAllLoading"
        :disabled="crud.selections.length === 0"
        @click="toDelete(crud.selections)"
      >
        删除
      </el-button>
      <el-button
        v-if="crud.optShow.download"
        :loading="crud.downloadLoading"
        :disabled="!crud.data.length"
        class="filter-item"
        size="mini"
        type="warning"
        icon="el-icon-download"
        @click="crud.doExport"
      >导出</el-button>
      <!--右侧-->
      <slot name="right" />
    </span>
    <el-button-group class="crud-opts-right">
      <el-button
        size="mini"
        plain
        type="info"
        icon="el-icon-search"
        @click="toggleSearch()"
      />
      <el-button
        size="mini"
        icon="el-icon-refresh"
        @click="crud.refresh()"
      />
      <el-popover
        placement="bottom-end"
        width="150"
        trigger="click"
      >
        <el-button
          slot="reference"
          size="mini"
          icon="el-icon-s-grid"
        >
          <i
            class="fa fa-caret-down"
            aria-hidden="true"
          />
        </el-button>
        <el-checkbox
          v-model="allColumnsSelected"
          :indeterminate="allColumnsSelectedIndeterminate"
          @change="handleCheckAllChange"
        >
          全选
        </el-checkbox>
        <el-checkbox
          v-for="item in tableColumns"
          :key="item.property"
          v-model="item.visible"
          @change="handleCheckedTableColumnsChange(item)"
        >
          {{ item.label }}
        </el-checkbox>
      </el-popover>
    </el-button-group>
  </div>
</template>
<script>
  import CRUD, { crud } from '@/components/f-crud/f-crud'

  function sortWithRef (src, ref) {
    const result = Object.assign([], ref)
    let cursor = -1
    src.forEach(e => {
      const idx = result.indexOf(e)
      if (idx === -1) {
        cursor += 1
        result.splice(cursor, 0, e)
      } else {
        cursor = idx
      }
    })
    return result
  }

  export default {
    mixins: [crud()],
    props: {
      permission: {
        type: Object,
        default: () => { return {} }
      },
      hiddenColumns: {
        type: Array,
        default: () => { return [] }
      },
      ignoreColumns: {
        type: Array,
        default: () => { return [] }
      }
    },
    data () {
      return {
        tableColumns: [],
        allColumnsSelected: true,
        allColumnsSelectedIndeterminate: false,
        tableUnwatcher: null,
        // 忽略下次表格列变动
        ignoreNextTableColumnsChange: false
      }
    },
    watch: {
      'crud.props.table' () {
        this.updateTableColumns()
        this.tableColumns.forEach(column => {
          if (this.hiddenColumns.indexOf(column.property) !== -1) {
            column.visible = false
            this.updateColumnVisible(column)
          }
        })
      },
      'crud.props.table.store.states.columns' () {
        this.updateTableColumns()
      }
    },
    created () {
      this.crud.updateProp('searchToggle', true)
    },
    methods: {
      updateTableColumns () {
        const table = this.crud.getTable()
        if (!table) {
          this.tableColumns = []
          return
        }
        let cols = null
        const columnFilter = e => e && e.type === 'default' && e.property && this.ignoreColumns.indexOf(e.property) === -1
        const refCols = table.columns.filter(columnFilter)
        if (this.ignoreNextTableColumnsChange) {
          this.ignoreNextTableColumnsChange = false
          return
        }
        this.ignoreNextTableColumnsChange = false
        const columns = []
        const fullTableColumns = table.$children.map(e => e.columnConfig).filter(columnFilter)
        cols = sortWithRef(fullTableColumns, refCols)
        cols.forEach(config => {
          const column = {
            property: config.property,
            label: config.label,
            visible: refCols.indexOf(config) !== -1
          }
          columns.push(column)
        })
        this.tableColumns = columns
      },
      toDelete (datas) {
        this.$confirm(`确认删除选中的${datas.length}条数据?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.crud.delAllLoading = true
          this.crud.doDelete(datas)
        }).catch(() => {
        })
      },
      handleCheckAllChange (val) {
        if (val === false) {
          this.allColumnsSelected = true
          return
        }
        this.tableColumns.forEach(column => {
          if (!column.visible) {
            column.visible = true
            this.updateColumnVisible(column)
          }
        })
        this.allColumnsSelected = val
        this.allColumnsSelectedIndeterminate = false
      },
      handleCheckedTableColumnsChange (item) {
        let totalCount = 0
        let selectedCount = 0
        this.tableColumns.forEach(column => {
          ++totalCount
          selectedCount += column.visible ? 1 : 0
        })
        if (selectedCount === 0) {
          this.crud.notify('请至少选择一列', CRUD.NOTIFICATION_TYPE.WARNING)
          this.$nextTick(function () {
            item.visible = true
          })
          return
        }
        this.allColumnsSelected = selectedCount === totalCount
        this.allColumnsSelectedIndeterminate = selectedCount !== totalCount && selectedCount !== 0
        this.updateColumnVisible(item)
      },
      updateColumnVisible (item) {
        const table = this.crud.props.table
        const vm = table.$children.find(e => e.prop === item.property)
        const columnConfig = vm.columnConfig
        if (item.visible) {
          // 找出合适的插入点
          const columnIndex = this.tableColumns.indexOf(item)
          vm.owner.store.commit('insertColumn', columnConfig, columnIndex + 1, null)
        } else {
          vm.owner.store.commit('removeColumn', columnConfig, null)
        }
        this.ignoreNextTableColumnsChange = true
      },
      toggleSearch () {
        this.crud.props.searchToggle = !this.crud.props.searchToggle
      }
    }
  }
</script>

<style>
  .crud-opts {
    padding: 4px 0;
    display: -webkit-flex;
    display: flex;
    align-items: center;
  }
  .crud-opts .crud-opts-right {
    margin-left: auto;
  }
</style>
